import React, {useState} from 'react';
import {App, Button, Drawer, Form} from "antd";
import {AsyncThunk, AsyncThunkConfig} from "@reduxjs/toolkit/dist/createAsyncThunk";
import {useAppDispatch} from "storage/redux/hook";
import {useLocation, useNavigate} from "react-router-dom";
import {PlusOutlined} from "@ant-design/icons";
import BaseEntity from "type/entity";
import {compareObject} from "util/compare";
import LogFactory from "log/LogFactory";
import {FormInstance} from "antd/lib/form/Form";


interface DrawerEnhanceProps<T extends BaseEntity> {
    /**
     * 抽屉标题
     */
    title?: string
    /**
     * 右侧操作按钮
     */
    extra?: React.ReactNode
    /**
     * 抽屉加载完成后的回调
     */
    afterOpenChange?: () => void
    /**
     * 抽屉大小
     */
    size?: "default" | "large"
    /**
     * 抽屉中表单的初始化值
     */
    initialValues?: Partial<T>,
    /**
     * 抽屉中表单提交的执行action
     */
    requestAction: AsyncThunk<any, T, AsyncThunkConfig>,
    /**
     * 表单数据转换器,用户根据需要实现此方法进行表单数据提交之前的转换
     * @param formData 表单提交的原始数据
     */
    formDataConverter?: (formData: T) => T,

    /**
     * 调用此方法确认表单是否可以提交到服务器,如果返回false则不提交表单
     * @param value 表单数据
     */
    isCommit?: (value: T) => boolean,
    /**
     * 更新的数据编号
     */
    updateId?: number,

    /** 表单子组件 */
    children?: React.ReactNode,
    /**
     * 表单提交成功后回调
     */
    commitSuccessCallBack?: (form: FormInstance<T>) => void
}

const log = LogFactory.getLogger("DrawerEnhance");

/**
 * 增强型抽屉组件
 * @param props 抽屉组件props
 * @constructor
 */
const DrawerEnhance =<T extends BaseEntity> (props: DrawerEnhanceProps<T>) => {
    const _state = useLocation().state;
    const [open, setOpen] = useState<boolean>(true);
    const [loading, setLoading] = React.useState(false);
    const dispatch = useAppDispatch();
    const navigate = useNavigate();
    const { message } = App.useApp();

    const [form] = Form.useForm<T>();

    const onClose = () => {
        setOpen(false);
        navigate("..", {state: _state});
    };

    const onFinish = async (value: T) => {
        if (props.isCommit && !props.isCommit(value)){
            message.info("表单内容不完整,请检查");
            return;
        }
        if (props.formDataConverter){
            value = props.formDataConverter(value);
        }
        if (_state.children) {
            const compRes = compareObject(_state.children as T, value);
            if (compRes === null) {
                message.info("数据没有修改");
                return;
            }
        }
        setLoading(true);
        value.id = props.updateId as number;
        const res = await dispatch(props.requestAction(value)).unwrap();
        if (res.success){
            message.success( props.updateId ? "修改成功" : "添加成功");
            props.commitSuccessCallBack && props.commitSuccessCallBack(form);
        }else {
            log.debug("表单提交失败", res);
            message.warning( props.updateId ? "修改失败" : "修改成功");
        }
        setLoading(false);
        if (props.updateId){
            navigate("..", {replace: true});
        }
    };
    return (
        <Drawer
            title={props.title}
            extra={props.extra}
            open={open}
            onClose={onClose}
            size={props.size || "default"}
            destroyOnClose
            maskClosable={false}
            // loading={loading}
            afterOpenChange={props.afterOpenChange}
        >
            <Form<T>
                form={form}
                layout={"vertical"}
                initialValues={props.initialValues}
                onFinish={onFinish}
            >
                {props.children}
                <Form.Item>
                    <Button icon={<PlusOutlined />} loading={loading} type={"primary"} htmlType={"submit"}>{ props.updateId ? "更新" : "添加"}</Button>
                </Form.Item>
            </Form>
        </Drawer>
    );
};

export default DrawerEnhance;